﻿#pragma once

#include "geom_curve.h"

namespace CAGD
{

/**
 * 离散分段曲线.
 */
template <int Dim> class GeomDiscreteCurveDim : public GeomCurveDim<Dim>
{
  public:
    /**
     * @brief 顶点构造.
     * @param points
     * @see
     */
    GeomDiscreteCurveDim(const std::vector<BPntN<Dim>> &points) : m_points(points)
    {
        for (int i = 0; i < points.size(); i++)
            m_paras.push_back(i);
    }

    /**
     * @brief 顶点附带参数.
     * @param points
     * @param paras
     * @see
     */
    GeomDiscreteCurveDim(const std::vector<BPntN<Dim>> &points, const std::vector<double> &paras)
        : m_points(points), m_paras(paras)
    {
    }

    /**
     * @brief 获得控制点.
     * @return
     * @see
     */
    const std::vector<BPntN<Dim>> &Poles() const
    {
        return m_points;
    }

    /**
     * @brief 设置控制点.
     * @param points
     * @see
     */
    void SetPoles(const std::vector<BPntN<Dim>> &points)
    {
        m_points = points;
    }

    /**
     * @brief 起始参数.
     * @return
     * @see
     */
    double FirstParameter() const override
    {
        return m_paras.front();
    }

    /**
     * @brief 终止参数.
     * @return
     * @see
     */
    double LastParameter() const override
    {
        return m_paras.back();
    }

    /**
     * @brief 控制点数.
     * @return
     * @see
     */
    int NbPoles() const
    {
        return m_points.size();
    }

    /**
     * @brief 取值函数.
     * @param t
     * @param P
     * @see
     */
    void D0(double t, BPntN<Dim> &P) const override
    {
        P = m_points[int(t)];
    }

    /**
     * @brief 切线函数.
     * @param t
     * @param P
     * @param V1
     * @see
     */
    void D1(double t, BPntN<Dim> &P, BVecN<Dim> &V1) const override
    {
    }

    /**
     * @brief 2 阶导函数.
     * @param t
     * @param P
     * @param V1
     * @param V2
     * @see
     */
    void D2(double t, BPntN<Dim> &P, BVecN<Dim> &V1, BVecN<Dim> &V2) const override
    {
    }

    /**
     * @brief n 阶导函数.
     * @param N
     * @param t
     * @param P
     * @param V
     * @see
     */
    void DN(int N, double t, BPntN<Dim> &P, std::vector<BVecN<Dim>> &V) const override
    {
    }

    /**
     * @brief 获得引用点.
     * @return
     * @see
     */
    std::vector<BPntN<Dim> *> MakeReference() override
    {
        std::vector<BPntN<Dim> *> reference;
        return reference;
    }

  protected:
    std::vector<BPntN<Dim>> m_points;
    std::vector<double> m_paras;
};

using Geom2dDiscreteCurve = GeomDiscreteCurveDim<2>;
using GeomDiscreteCurve = GeomDiscreteCurveDim<3>;

} // namespace CAGD
